#include "ExpressionEvaluator.h"
#include <QStack>

ExpressionEvaluator::ExpressionEvaluator()
{
}

int ExpressionEvaluator::m_priority(QChar op)
{
    if (op == '+' || op == '-')
        return 1;
    if (op == '*' || op == '/')
        return 2;
    return 0;
}

QString ExpressionEvaluator::evaluate(const QString &expression)
{
    QStack<double> values;
    QStack<QChar> ops;

    int i = 0;
    while (i < expression.length()) {
        if (expression[i].isDigit()) {
            double value = 0;
            while (i < expression.length() && expression[i].isDigit()) {
                value = value * 10 + expression[i].digitValue();
                i++;
            }
            values.push(value);
        } else {
            QChar op = expression[i];
            while (!ops.isEmpty() && m_priority(ops.top()) >= m_priority(op)) {
                double val2 = values.pop();
                double val1 = values.pop();
                QChar op = ops.pop();

                switch (op.unicode()) {
                case '+': values.push(val1 + val2); break;
                case '-': values.push(val1 - val2); break;
                case '*': values.push(val1 * val2); break;
                case '/':
                    if (val2 != 0)
                        values.push(val1 / val2);
                    else
                        return "Error: Division by zero";
                    break;
                }
            }
            ops.push(op);
            i++;
        }
    }

    while (!ops.isEmpty()) {
        double val2 = values.pop();
        double val1 = values.pop();
        QChar op = ops.pop();

        switch (op.unicode()) {
        case '+': values.push(val1 + val2); break;
        case '-': values.push(val1 - val2); break;
        case '*': values.push(val1 * val2); break;
        case '/':
            if (val2 != 0)
                values.push(val1 / val2);
            else
                return "Error: Division by zero";
            break;
        }
    }

    return QString::number(values.top());
}
